/*
 * nipc.c
 *
 *  Created on: 15/09/2011
 *      Author: utn_so
 */


#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include "nipc.h"


void nipc_make(nipcMessage *nipc, int pDescriptor, unsigned char type, short int pLength, char *payload)
{
		sprintf(nipc->payloadID,"%d", pDescriptor);
        nipc->type = type;
        nipc->payloadLength = pLength;

        if(pLength)
               nipc->payload = payload;
        else
               nipc->payload = NULL;
}

void nipc_0payload(nipcMessage *nipc, int pDescriptor)
{
        nipc->payload = NULL;
        nipc->payloadLength = 0;
        nipc->type = 0;
        memset(nipc->payloadID, 0, 6);
        sprintf(nipc->payloadID,"%d", pDescriptor);
}

void nipc_freepayload(nipcMessage *nipc)
{
		/*log_debug(log, thread_name, format);*/

        free(nipc->payload);
        nipc->payload = NULL;
        nipc->payloadLength = 0;
        sprintf(nipc->payloadID,"%d", 0);
}
int nipc_recv(nipcMessage *nipc, int pDescriptor)
{
        char            buffer[10];
        unsigned int    len = 0;
        short int    *pl = NULL;

        if(!nipc)
        {
        	/*log_error(log, thread_name, format);*/
                return NIPC_ERROR;
        }

        nipc->payload = NULL;
        nipc->payloadLength = 0;

        len = recv(pDescriptor, buffer, 10, 0);

        if(len != 10)
        {
                if(!len)
                {
                      return NIPC_CONNECTION_LOST;
                }
                /*error al recibir datos*/
                return NIPC_ERROR;
       }

        memcpy(nipc->payloadID, buffer, 6);

        nipc->type = buffer[6];

        pl = (short int*)&buffer[7];

        nipc->payloadLength = ntohs(*pl);

        if(nipc->payloadLength)
        {
        	nipc->payload = (char *) malloc(nipc->payloadLength);
        	if(NULL == nipc->payload)
        	{
        		//LOG(LOG_ERROR, "MALLOC FAILED.");
        	}

        	len = recv(pDescriptor, nipc->payload, nipc->payloadLength, 0);
        	if(!len)
        	{
        		free(nipc->payload);
        		nipc->payload = NULL;
        		return NIPC_CONNECTION_LOST;
        	}
        	if(len != nipc->payloadLength)
        	{
        		//LOG(LOG_DEBUG, "mps_recv: tamaño de payload invalido");
        		nipc->payload = NULL;
        		return -1;
        	}
        } else {
        	nipc->payload = NULL;
        }
    return NIPC_ERROR_NONE;
}

int nipc_send(nipcMessage *nipc, int pDescriptor)
{
	char                    buffer[10];
	int                     aux = 0;
	short int    *pl = NULL;

	memcpy(buffer, nipc->payloadID, 6);

	buffer[6] = nipc->type;

	pl = (short int*)&buffer[7];

	*pl = htons(nipc->payloadLength);

	aux = send(pDescriptor, buffer, 10, 0);

	if(aux != 10)
	{
		//LOG(LOG_DEBUG, "mps_send: error al enviar datos");
		return -1;
	}
	if(nipc->payloadLength)
//		nipc->payload = (char *) malloc(nipc->payloadLength);
		aux = send(pDescriptor, nipc->payload, nipc->payloadLength , 0);
	if(aux > 0)
		return NIPC_ERROR_NONE;
	else
		return aux;
}

int sockets_open_server(char *ip, unsigned short port, int slots)
{
        struct sockaddr_in dir;
        int descriptor;


        dir.sin_family = AF_INET;
        dir.sin_addr.s_addr = inet_addr(ip);
        dir.sin_port = htons(port);
        memset(dir.sin_zero, 0, sizeof(dir.sin_zero));


        if(-1 == (descriptor = socket(AF_INET, SOCK_STREAM, 0)))
                return -1;


        if(-1 == bind(descriptor, (struct sockaddr*)&dir, sizeof(dir)))
         {
               close(descriptor);
                return -1;
        }

        if(-1 == listen(descriptor, slots))
        {
                close(descriptor);
                return -1;
        }

        return descriptor;

}
int sockets_open_client(char *ip, unsigned short port)
{
	struct sockaddr_in  dir;
	int 				descriptor;

	dir.sin_family = AF_INET;
	dir.sin_addr.s_addr = inet_addr(ip);
	dir.sin_port = htons(port);
	memset(dir.sin_zero, 0, sizeof(dir.sin_zero));

	if(-1  == (descriptor = socket(AF_INET, SOCK_STREAM, 0)))
	{
		return -1;
	}

	if(-1 == connect(descriptor, (struct sockaddr*)&dir, sizeof(dir)))
	{
		perror("connecting");
		close(descriptor);
		return -1;
	}

return descriptor;
}

